package com.golang.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.golang.common.dto.ResponseParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.validation.constraints.NotNull;
import java.nio.charset.StandardCharsets;

/**
 * token验证过滤器
 */
@Slf4j
@Component
public class GatewayTokenFilter implements GlobalFilter, Ordered {
/*
    @Autowired
    RedisClientService redisClientService;*/


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

/*        if (request.getMethod() == HttpMethod.POST) {
            AtomicReference<String> requestBody = new AtomicReference<>("");
            RecorderServerHttpRequestDecorator requestDecorator = new RecorderServerHttpRequestDecorator(request);
            Flux<DataBuffer> body = requestDecorator.getBody();
            body.subscribe(buffer -> {
                CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
                requestBody.set(charBuffer.toString());
            });
            if (requestBody == null) {
                return getVoidMono(exchange, new ResponseParam<>(new ResponseHeader("403", "token不能空！")), HttpStatus.OK);

            }
            ObjectMapper mapper = new ObjectMapper();
            RequestParam requestParam = null;
            try {
                requestParam = mapper.readValue(requestBody.get(), RequestParam.class);

                RequestHeader header = requestParam.getHeader();
                if (header == null) {
                    return getVoidMono(exchange, new ResponseParam<>(new ResponseHeader("400", "请求参数Header不能为空")), HttpStatus.OK);
                }
                String token = header.getToken();
                if (StringUtils.isEmpty(token)) {
                    return getVoidMono(exchange, new ResponseParam<>(new ResponseHeader("403", "token不能空")), HttpStatus.OK);
                }
                TokenUserInfo tokenUser = redisClientService.getTokenUserInfoByToken(token);

                if (tokenUser == null) {//token校验失败
                    return getVoidMono(exchange, new ResponseParam<>(new ResponseHeader("403", "用户未登录或者会话已过期，请重新登录！")), HttpStatus.OK);
                } else {
                    redisClientService.expire(token, 600000);
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                return getVoidMono(exchange, new ResponseParam<>(new ResponseHeader("500", "服务器内部错误")), HttpStatus.OK);
            }
        }
        if (HttpMethod.GET == request.getMethod()) {
            log.info("request param:{}", request.getQueryParams().toSingleValueMap());
        }*/
        return chain.filter(exchange);
    }

    /**
     * 业务拦截提示
     *
     * @param body
     */
    @NotNull
    private Mono<Void> getVoidMono(ServerWebExchange serverWebExchange, ResponseParam body, HttpStatus status) {
        serverWebExchange.getResponse().setStatusCode(status);
        serverWebExchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
        byte[] bytes = JSONObject.toJSONString(body).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = serverWebExchange.getResponse().bufferFactory().wrap(bytes);
        return serverWebExchange.getResponse().writeWith(Flux.just(buffer));
    }

    @Override
    public int getOrder() {
        return -100;
    }
}
